package service;

import exception.BusinessException;
import model.*;
import repository.OrderRepository;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单服务实现
 */
public class SimpleOrderService extends BaseOrderService {
    // 最大商品数量限制
    private static final int MAX_ITEMS = 5;
    // 订单自动取消时间（分钟）
    private static final int AUTO_CANCEL_MINUTES = 30;
    // 冰咖啡停售时间
    private static final LocalTime ICED_COFFEE_CUT_OFF = LocalTime.of(15, 0);

    public SimpleOrderService(OrderRepository repository) {
        super(repository);
    }

    @Override
    public Order createOrder(List<Item> items, boolean isVIP, LocalDateTime currentTime) {
        // 基础校验
        validateOrderItems(items);

        // 处理时间敏感商品
        List<Item> filteredItems = new ArrayList<>(items);
        List<String> remarks = new ArrayList<>();
        filterTimeSensitiveItems(filteredItems, remarks, currentTime.toLocalTime());

        // 再次校验，确保过滤后的商品列表仍然满足规则
        if (filteredItems.isEmpty()) {
            throw new BusinessException("EMPTY_ORDER", "订单不能为空");
        }
        validateOrderItems(filteredItems);

        // 计算价格与应用促销规则
        double totalPrice = calculateTotalPrice(filteredItems, isVIP);

        // 创建订单
        Order order = new Order(
                UUID.randomUUID().toString(),
                filteredItems,
                OrderStatus.CREATED,
                totalPrice,
                currentTime
        );

        // 添加备注
        remarks.forEach(order::addRemark);

        // 保存订单
        repository.save(order);
        return order;
    }

    @Override
    public void cancelOrder(String orderId, LocalDateTime currentTime) {
        Order order = repository.findById(orderId);
        if (order == null) {
            throw new BusinessException("ORDER_NOT_FOUND", "订单不存在: " + orderId);
        }

        // 检查订单状态
        if (order.getStatus() == OrderStatus.PAID) {
            throw new BusinessException("CANNOT_CANCEL_PAID", "已支付的订单不可取消");
        }

        // 检查是否超时自动取消
        if (order.getStatus() == OrderStatus.CREATED) {
            long minutesPassed = ChronoUnit.MINUTES.between(order.getCreateTime(), currentTime);

            if (minutesPassed >= AUTO_CANCEL_MINUTES) {
                order.setStatus(OrderStatus.CANCELLED);
                order.addRemark("订单已超时自动取消");
                repository.updateStatus(orderId, OrderStatus.CANCELLED);
            } else {
                order.setStatus(OrderStatus.CANCELLED);
                order.addRemark("用户主动取消订单");
                repository.updateStatus(orderId, OrderStatus.CANCELLED);
            }
        }
    }

    /**
     * 校验订单商品是否满足规则
     */
    private void validateOrderItems(List<Item> items) {
        // 检查订单是否为空
        if (items == null || items.isEmpty()) {
            throw new BusinessException("EMPTY_ORDER", "订单不能为空");
        }

        // 检查订单商品数量是否超过限制
        if (items.size() > MAX_ITEMS) {
            throw new BusinessException("TOO_MANY_ITEMS", "单笔订单最多包含" + MAX_ITEMS + "个商品项");
        }

        // 检查是否包含主食
        boolean hasMainDish = items.stream()
                .anyMatch(item -> item.getType() == ItemType.MAIN);
        if (!hasMainDish) {
            throw new BusinessException("NO_MAIN_DISH", "订单必须包含至少一个主食");
        }

        // 检查甜品是否单独购买
        boolean hasDessert = items.stream()
                .anyMatch(item -> item.getType() == ItemType.DESSERT);
        if (hasDessert && !hasMainDish) {
            throw new BusinessException("DESSERT_ALONE", "甜品不能单独购买（必须搭配主食）");
        }
    }

    /**
     * 过滤时间敏感商品
     */
    private void filterTimeSensitiveItems(List<Item> items, List<String> remarks, LocalTime currentTime) {
        // 处理冰咖啡时间限制
        items.removeIf(item -> {
            if ("冰咖啡".equals(item.getName()) && currentTime.isAfter(ICED_COFFEE_CUT_OFF)) {
                remarks.add("冰咖啡已下架（15点后不供应）");
                return true;
            }
            return false;
        });
    }

    /**
     * 计算总价并应用促销规则
     */
    /**
     * 计算总价并应用促销规则
     */
    private double calculateTotalPrice(List<Item> items, boolean isVIP) {
        // 复制一份商品列表，避免修改原始列表
        List<Item> itemsToProcess = new ArrayList<>(items);
        double totalPrice = 0.0;

        // 1. 先检查套餐优惠：汉堡 + 薯条 = 25元
        boolean hasHamburger = false;
        boolean hasFries = false;
        Item hamburgerItem = null;
        Item friesItem = null;

        // 查找汉堡和薯条
        for (Item item : itemsToProcess) {
            if ("汉堡".equals(item.getName()) && item.getType() == ItemType.MAIN) {
                hasHamburger = true;
                hamburgerItem = item;
            } else if ("薯条".equals(item.getName()) && item.getType() == ItemType.MAIN) {
                hasFries = true;
                friesItem = item;
            }
        }

        // 应用套餐优惠
        if (hasHamburger && hasFries) {
            totalPrice += 25.0;
            itemsToProcess.remove(hamburgerItem);
            itemsToProcess.remove(friesItem);
        }

        // 2. 处理饮料第二杯半价
        Map<String, List<Item>> drinkGroups = new HashMap<>();

        // 分组收集饮料
        List<Item> drinksToRemove = new ArrayList<>();
        for (Item item : itemsToProcess) {
            if (item.getType() == ItemType.DRINK) {
                drinkGroups.computeIfAbsent(item.getName(), k -> new ArrayList<>()).add(item);
                drinksToRemove.add(item);
            }
        }

        // 从待处理列表中移除所有饮料
        itemsToProcess.removeAll(drinksToRemove);

        // 计算饮料价格（应用第二杯半价）
        for (List<Item> drinkGroup : drinkGroups.values()) {
            double drinkPrice = drinkGroup.get(0).getPrice();
            int count = drinkGroup.size();

            // 每两杯中，第一杯全价，第二杯半价
            int fullPriceCount = (count + 1) / 2;  // 向上取整
            int halfPriceCount = count / 2;  // 向下取整

            totalPrice += (drinkPrice * fullPriceCount) + (drinkPrice * 0.5 * halfPriceCount);
        }

        // 3. 计算剩余商品的价格
        for (Item item : itemsToProcess) {
            totalPrice += item.getPrice();
        }

        // 4. 应用VIP折扣（最后计算）
        if (isVIP) {
            totalPrice *= 0.9;  // 9折
        }

        return totalPrice;
    }

    /**
     * 套餐组合优惠：汉堡 + 薯条 = 25元
     * 返回true表示应用了优惠，false表示未应用
     */
    private boolean applyComboDiscount(List<Item> items) {
        Optional<Item> hamburger = findAndRemoveItem(items, "汉堡", ItemType.MAIN);
        Optional<Item> fries = findAndRemoveItem(items, "薯条", ItemType.MAIN);

        return hamburger.isPresent() && fries.isPresent();
    }

    /**
     * 查找并移除指定名称和类型的商品
     */
    private Optional<Item> findAndRemoveItem(List<Item> items, String name, ItemType type) {
        return items.stream()
                .filter(item -> name.equals(item.getName()) && type == item.getType())
                .findFirst()
                .map(item -> {
                    items.remove(item);
                    return item;
                });
    }

    /**
     * 应用第二杯半价优惠
     * 返回计算后的饮料总价
     */
    private double applySecondDrinkDiscount(List<Item> items) {
        // 提取所有饮料
        List<Item> drinks = items.stream()
                .filter(item -> item.getType() == ItemType.DRINK)
                .collect(Collectors.toList());

        // 从原列表中移除所有饮料
        items.removeAll(drinks);

        // 按饮料名称分组
        Map<String, List<Item>> drinkGroups = drinks.stream()
                .collect(Collectors.groupingBy(Item::getName));

        double drinksTotal = 0.0;

        // 处理每组饮料的第二杯半价优惠
        for (List<Item> sameNameDrinks : drinkGroups.values()) {
            int count = sameNameDrinks.size();
            double price = sameNameDrinks.get(0).getPrice();

            // 计算全价杯数和半价杯数
            int fullPriceCount = (count + 1) / 2; // 向上取整
            int halfPriceCount = count / 2;       // 向下取整

            drinksTotal += (fullPriceCount * price) + (halfPriceCount * price * 0.5);
        }

        return drinksTotal;
    }
    public Order modifyOrder(String orderId, OrderModificationRequest request) {
        // 1. 检查订单是否存在
        Order order = repository.findById(orderId);
        if (order == null) {
            throw new BusinessException("ORDER_NOT_FOUND");
        }
        if (order.getStatus() != OrderStatus.UNPAID) {
            throw new BusinessException("MODIFY_FORBIDDEN");
        }
        switch (request.getModifyType()) {
            case FULL_REPLACE:
                // 处理整单替换逻辑
                break;
            case PARTIAL_MODIFY:
                handlePartialModification(order, request);
                break;
            default:
                throw new BusinessException("INVALID_MODIFY_TYPE");
        }
        // 8. 执行修改
        Order updatedOrder = repository.save(order);

        // 9. 记录操作日志

        return updatedOrder;
    }

    private void handlePartialModification(Order order, OrderModificationRequest request) {
        // 4. 检查商品有效性
        validateItems(request.getModifiedItems());

    }

    private void validateItems(List<Item> modifiedItems) {

    }

}